package com.mk.ssm.service.impl;

import com.mk.ssm.aop.MethodCache;
import com.mk.ssm.bean.dto.RoleDto;
import com.mk.ssm.bean.entity.Resource;
import com.mk.ssm.bean.entity.Role;
import com.mk.ssm.bean.entity.User;
import com.mk.ssm.cache.RedisCache;
import com.mk.ssm.mapper.RoleMapper;
import com.mk.ssm.mapper.UserMapper;
import com.mk.ssm.service.ResourceService;
import com.mk.ssm.service.RoleService;
import com.mk.ssm.utils.Constants;
import com.mk.ssm.utils.ResultUtil;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>Resource: yankee
 * <p>Date: 17-4-3
 * <p>Version: 1.0
 */
@Service
public class RoleServiceImpl implements RoleService {
    private final Logger LOG = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RoleMapper roleDao;
    @Autowired
    private ResourceService resourceService;
    @Autowired
    private RedisCache cache;
    @Autowired
    private UserMapper userMapper;

    public int createRole(Role role) {
        Integer res;
        role.setAble(Constants.ABLE_CONFIG.DEFAULT_ABLE);
        if(role.getRole() != null && !"".equals(role.getRole())
                && role.getDescription() != null && !"".equals(role.getDescription())) {
            try {
                RoleDto roleDto = new RoleDto();
                //完美的复制
                BeanUtils.copyProperties(roleDto,role);
                Integer sum = 0;
                //去数据库中查找所有传入的资源是否可以在数据库中找到
                if(role.getResourceIds() != null && role.getResourceIds().size() > 0) {
                    for (int j = 0; j < role.getResourceIds().size(); j++) {
                        Resource resource = resourceService.findOne(role.getResourceIds().get(j));
                        if (resource != null)
                            sum++;
                    }
                    //查到的条数与传入的条数相同就添加
                    if (sum == role.getResourceIds().size()) {
                        roleDto.setResourceIds(role.getResourceIdsStr());
                        res = roleDao.createRole(roleDto);
                        System.out.println("################id=" + roleDto.getId());
                    } else
                        res = ResultUtil.RESULT_CONFIG.RESULT_NUM06;
                }else{
                    res = roleDao.createRole(roleDto);
                    System.out.println("################id=" + roleDto.getId());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM01;
            } catch (InvocationTargetException e) {
                e.printStackTrace();
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM02;
            }
        }else
            //传入的角色信息中缺少属性
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM05;
        return res;
    }

    public int updateRole(Role role) {
        Integer res;
        Role role1 = roleDao.findOne(role.getId(), Constants.ABLE_CONFIG.ABLE);
        if(role1 != null) {
            try {
                RoleDto roleDto = new RoleDto();
                BeanUtils.copyProperties(roleDto,role);
                if(role.getAble() == null)
                    roleDto.setAble(null);
                //判断选择的资源信息是否为空
                if(role.getResourceIds() != null && role.getResourceIds().size() > 0) {
                    Integer sum = 0;
                    for (int j = 0; j < role.getResourceIds().size(); j++) {
                        Resource resource = resourceService.findOne(role.getResourceIds().get(j));
                        //在数据库中查找是否有对应的资源信息
                        if(null != resource){
                            sum++;
                        }
                    }
                    //在数据库中可以查到所有的资源信息就修改
                    if(sum == role.getResourceIds().size()){
                        roleDto.setResourceIds(role.getResourceIdsStr());
                        res = roleDao.updateRole(roleDto);
                    }else
                        //修改时传入的角色信息中资源有部分在数据库中找不到
                        res = ResultUtil.RESULT_CONFIG.RESULT_NUM06;
                }else if((role.getRole() == null || "".equals(role.getRole()))
                        && (role.getDescription() == null || "".equals(role.getDescription()))
                        && (role.getResourceIds() == null || role.getResourceIds().size() == 0)
                        && role.getAble() == null){
                    res = ResultUtil.RESULT_CONFIG.RESULT_NUM05;
                }else {
                    roleDto.setResourceIds(null);
                    res = roleDao.updateRole(roleDto);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM01;
            } catch (InvocationTargetException e) {
                e.printStackTrace();
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM02;
            }
        }else
            //传入的角色id信息找不到对应的信息
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM05;
        return res;
    }

    public int deleteRole(Long roleId) {
        Integer res;
        Role role = roleDao.findOne(roleId, Constants.ABLE_CONFIG.ABLE);
        List<User> userList = userMapper.findAll(Constants.ABLE_CONFIG.ABLE);
        if(role != null) {
            //admin不可删除
            if("admin".equals(role.getRole())){
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM05;
            }else {
                //遍历用户，如果角色信息在被用户使用就不删除
                for (int i = 0; i < userList.size(); i++) {
                    List<Long> roleIds = userList.get(i).getRoleIds();
                    for (int j = 0; j < roleIds.size(); j++) {
                        if (role.getId() == roleIds.get(j)) {
                            res = ResultUtil.RESULT_CONFIG.RESULT_NUM01;
                            return res;
                        }
                    }
                }
                res = roleDao.deleteRole(roleId, Constants.ABLE_CONFIG.UNABLE);
            }
        }else
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM02;
        return res;
    }

    @Override
    @MethodCache(clz = Role.class)
    public Role findOne(Long roleId) {
        return roleDao.findOne(roleId, Constants.ABLE_CONFIG.ABLE);
    }

    @Override
    @MethodCache(isCollection = 1, clz = Role.class)
    public List<Role> findAll() {
        List<Role> roleList = roleDao.findAll(Constants.ABLE_CONFIG.ABLE);
        for (int i = 0; i < roleList.size(); i++) {
            List<Long> resourceList = roleList.get(i).getResourceIds();
            //根据资源编号查出对应的资源名称
            roleList.get(i).setResName(findResourceName(resourceList));
        }
        return roleList;
    }

    @Override
    @MethodCache(isCollection = 1, clz = String.class)
    public List<String> findRoles(List<Long> roleIds) {
        List<String> list = new ArrayList<String>();
        for (Long roleId : roleIds) {
            Role role = findOne(roleId);
            if (role != null) {
                list.add(role.getRole());
            }
        }
        return list;
    }

    @Override
    @MethodCache(isCollection = 1, clz = String.class)
    public List<String> findPermissions(List<Long> roleIds) {
        List<Long> resourceIds = new ArrayList<Long>();
        for (Long roleId : roleIds) {
            Role role = findOne(roleId);
            if (role != null) {
                resourceIds.addAll(role.getResourceIds());
            }
        }
        return resourceService.findPermissions(resourceIds);
    }

    /**
     * 根据对应的资源编号查出资源名称
     * @param resourceList
     * @return
     */
    private String findResourceName(List<Long> resourceList){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < resourceList.size(); i++) {
            Resource resource = resourceService.findOne(resourceList.get(i));
            if(resource != null) {
                sb.append(resource.getName());
                sb.append(",");
            }
        }
        if(sb.length() > 0)
            sb.deleteCharAt(sb.length()-1);
        return sb.toString();
    }
}
